package com.tiancheng.trade.merchant.channel.handler.gaocheng;

import com.tiancheng.commom.pay.gaocheng.GcPayChannel;
import com.tiancheng.commom.pay.gaocheng.GcPayProperties;
import com.tiancheng.commom.pay.gaocheng.req.merchant.*;
import com.tiancheng.commom.pay.gaocheng.res.GcBaseResp;
import com.tiancheng.commom.pay.gaocheng.res.merchant.GcMerchantApplyBaseRes;
import com.tiancheng.commom.pay.gaocheng.res.merchant.GcMerchantApplyRes;
import com.tiancheng.trade.commom.core.data.ApplicationInfo;
import com.tiancheng.trade.commom.core.enums.MerchantRegStatusEnums;
import com.tiancheng.trade.commom.core.enums.PaymentChannelEnum;
import com.tiancheng.trade.commom.core.exception.Asserts;
import com.tiancheng.trade.commom.core.exception.BusinessException;
import com.tiancheng.trade.commom.core.exception.error.BusinessErrorInfoEnum;
import com.tiancheng.trade.commom.core.utils.IdWorkerUtils;
import com.tiancheng.trade.commom.core.utils.JsonUtil;
import com.tiancheng.trade.commom.web.model.request.merchant.MerchantBranchBankListReqVO;
import com.tiancheng.trade.commom.web.model.response.MerchantBranchBankListResVO;
import com.tiancheng.trade.commom.core.utils.DateTimeUtil;
import com.tiancheng.trade.merchant.channel.AbstractMerchantRegChannel;
import com.tiancheng.trade.merchant.channel.IdPhotoEnums;
import com.tiancheng.trade.merchant.channel.bo.MerchantRegSmsSendBO;
import com.tiancheng.trade.merchant.channel.bo.MerchantRegSmsVerifyBO;
import com.tiancheng.trade.merchant.channel.config.GcChannelProperties;
import com.tiancheng.trade.merchant.channel.handler.ums.request.*;
import com.tiancheng.trade.merchant.convert.MerchantConvert;
import com.tiancheng.trade.merchant.dto.message.ChannelNotifyMessage;
import com.tiancheng.trade.merchant.dto.requestdto.MerchantPayPivRegVO;
import com.tiancheng.trade.merchant.dto.requestdto.MerchantPayRegVO;
import com.tiancheng.trade.merchant.dto.requestdto.MinioUploadDto;
import com.tiancheng.trade.merchant.dto.responsedto.MerchantRegStatusQueryResDTO;
import com.tiancheng.trade.merchant.enums.MerchantTypeEnums;
import com.tiancheng.trade.merchant.model.MerchantPayReg;
import com.tiancheng.trade.merchant.model.MerchantPayRegFile;
import com.tiancheng.trade.merchant.service.IUploadService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Slf4j
@Component
public class GcMerchantRegChannel implements AbstractMerchantRegChannel {

    public static final int FILE_MAX_SIZE = 2 * 1024 * 1024;

    @Resource
    private IUploadService uploadService;
    @Resource
    private GcChannelProperties gcChannelProperties;

    @Override
    public MerchantPayRegFile upload(MultipartFile file, Integer regMode, MinioUploadDto upload) {
        final long size = file.getSize();
        BusinessErrorInfoEnum.MERCHANT_REG_ID_PHOTO_SIZE_ERROR.assertIsTrue(size < FILE_MAX_SIZE);
        MerchantPayRegFile merchantPayRegFile = new MerchantPayRegFile();
        merchantPayRegFile.setFilePath(upload.getUrl());
        String originalFilename = file.getOriginalFilename();
        merchantPayRegFile.setFileType(originalFilename.split("\\.")[1]);
        merchantPayRegFile.setFileSize(String.valueOf(size));
        merchantPayRegFile.setChannelRegId(IdWorkerUtils.getInstance().buildPartNumber());
        return merchantPayRegFile;
    }

    @Override
    public MerchantPayReg complexUpload(ApplicationInfo applicationInfo, MerchantPayRegVO params) {

        GcChannelProperties.GcChannelPropertiesItem config = gcChannelProperties.getByOrgPayChannelId(applicationInfo.getOrgPaymentChannelId());
        Asserts.isTrue(null != config, "配置文件异常，请联系管理员处理！");
        Asserts.isTrue(CollectionUtils.isNotEmpty(params.getPicList()), "证件列表为空！");
        GcMerchantApplyReq applyReq = new GcMerchantApplyReq();

        applyReq.setApplyUpdate(false);
        applyReq.setApplyNo(IdWorkerUtils.getInstance().createUUID());
        applyReq.setIndustry(params.getMccCode());
        applyReq.setManageName(params.getShopName());
        applyReq.setCardType(params.getBankAcctType());
        applyReq.setAccountNo(params.getBankAcctNo());
        applyReq.setAccountName(params.getBankAcctName());
        applyReq.setAccountMobile(params.getLegalMobile());
        applyReq.setAccountBank(params.getBankNo());
        if (StringUtils.isNotEmpty(params.getLegalCardBeginDate())) {
            applyReq.setPersonCertDate1(DateTimeUtil.format(DateTimeUtil.formatDate(params.getLegalCardBeginDate(), "yyyy-MM-dd"), "yyyyMMdd"));
        }
        if (StringUtils.isNotEmpty(params.getLegalCardDeadline())) {
            applyReq.setPersonCertDate2(DateTimeUtil.format(DateTimeUtil.formatDate(params.getLegalCardDeadline(), "yyyy-MM-dd"), "yyyyMMdd"));
        }
        applyReq.setContactName(params.getLegalName());
        applyReq.setContactPhone(params.getLegalMobile());
        applyReq.setContactCert(params.getLegalIdcardNo());
        applyReq.setServicePhone(params.getLegalMobile());
        applyReq.setAnnounce(1);
        applyReq.setApproveBack(config.getNotifyUrl());

        GcPayChannel gcPayChannel = new GcPayChannel(initGcPayConfig(applicationInfo.getOrgPaymentChannelId()));
        // 1、注册商户主体
        GcMerchantApplyBaseReq applyBaseReq = new GcMerchantApplyBaseReq();
        applyBaseReq.setCorpName(params.getShopName());
        // 企业证件类型：U2-营业执照，U2-统一社会信用代码
        applyBaseReq.setCorpCertType("U2");
        applyBaseReq.setCorpCertNo(params.getShopLic());
        applyBaseReq.setCorpAddr(params.getShopAddrExt());
        if (StringUtils.isNotEmpty(params.getShopLicenseEndDate())) {
            applyBaseReq.setCorpCertDateEnd(DateTimeUtil.format(DateTimeUtil.formatDate(params.getShopLicenseEndDate(), DateTimeUtil.YYYYMMDD_INTERVAL), DateTimeUtil.yyyyMMdd));
        }
        if (params.getRegMerType().equals("00")) {
            // 企业
            applyBaseReq.setMchType(2);
        } else if (params.getRegMerType().equals("01")) {
            // 企业
            applyBaseReq.setMchType(3);
        }
        applyBaseReq.setPersonName(params.getLegalName());
        applyBaseReq.setPersonCertNo(params.getLegalIdcardNo());
        applyBaseReq.setPersonCertType("D1");
        applyBaseReq.setPersonResidence(params.getLegalmanHomeAddr());
        GcBaseResp<GcMerchantApplyBaseRes> applyResult = gcPayChannel.apply(applyBaseReq);
        Asserts.isTrue(applyResult.isOk() && applyResult.getData().getStatus().equals(1),"高诚-注册主体商户异常");
        applyReq.setMchNo(applyResult.getData().getMchNo());
        // 2、商户入驻申请
        GcBaseResp<GcMerchantApplyRes> merchantApplyRes = gcPayChannel.merchantApply(applyReq);
        Asserts.isTrue(merchantApplyRes.isOk()&& !merchantApplyRes.getData().getStatus().equals(2),"高诚-提交商户进件信息异常");
        // 3、商户附件资料上传
        for (MerchantPayPivRegVO merchantPayPivRegVO : params.getPicList()) {
            try {
                String fileType = getFileType(merchantPayPivRegVO.getDocumentType());
                if (StringUtils.isNotEmpty(fileType)) {
                    MultipartFile multipartFile = uploadService.downLoad(merchantPayPivRegVO.getFilePath());
                    GcMerchantUploadReq uploadFile = new GcMerchantUploadReq();
                    uploadFile.setType(fileType);
                    uploadFile.setFile(multipartFile);
                    uploadFile.setApplyNo(applyReq.getApplyNo());
                    gcPayChannel.upload(uploadFile);
                }

            } catch (Exception e) {
                log.error("上传证件信息异常:", e);
                throw new BusinessException("上传证件信息异常！");
            }
        }
        // 4、商户附件确认
        GcMerchantUploadConfirmReq gcMerchantUploadConfirmReq = new GcMerchantUploadConfirmReq();
        gcMerchantUploadConfirmReq.setApplyNo(applyReq.getApplyNo());
        GcBaseResp<GcMerchantApplyRes> gcMerchantApplyResGcBaseResp = gcPayChannel.uploadConfirm(gcMerchantUploadConfirmReq);
        log.info("高诚商户入驻附件确认返回：{}", JsonUtil.toJsonString(gcMerchantApplyResGcBaseResp));
        final MerchantPayReg merchantPayReg = MerchantConvert.INSTANCE.convert2MerchantPayReg(params);
        merchantPayReg.setApplyStatus(0);
        merchantPayReg.setIsChain(1);
        merchantPayReg.setChannelRegId(applyReq.getApplyNo());
        merchantPayReg.setChannelMerNo(applyResult.getData().getMchNo());
        merchantPayReg.setCompanyNo(applyResult.getData().getMchNo());

        /*final MerchantPayReg merchantPayReg = MerchantConvert.INSTANCE.convert2MerchantPayReg(merchantPayRegVO);
        merchantPayReg.setApplyStatus(0);
        merchantPayReg.setIsChain(1);
        merchantPayReg.setChannelRegId(params.getRequest_seq());*/
        return merchantPayReg;
    }

    /**
     * 文件类型转换
     *
     * @param documentType
     * @return
     */
    private String getFileType(String documentType) {
        if (StringUtils.isNotEmpty(documentType)) {
            return null;
        }
        Optional<IdPhotoEnums> idPhotoEnumsOp = IdPhotoEnums.getByCode(documentType);
        if (idPhotoEnumsOp.isEmpty()) {
            return null;
        }
        return switch (idPhotoEnumsOp.get()) {
            case sh_yyzz ->
                // 营业执照
                    "1";
            case fr_sfz ->
                // 身份证人像面
                    "21";
            case fr_sfz_fm ->
                // 身份证国徽面
                    "22";
            case mtzp ->
                // 经营场所照（门头）
                    "41";
            case snzp, qtcl ->
                // 经营场所照（环境）
                    "42";
            case yhkh_hz ->
                // 银行（开户）回执
                    "3";
            default -> null;
        };
    }

    @Override
    public List<MerchantBranchBankListResVO> branchBankList(MerchantBranchBankListReqVO merchantBranchBankListReqVO) {
        return null;
    }

    @Override
    public String queryRegin(String dataType) {
        return null;
    }

    @Override
    public void requestAccountVerify(UmsMerchantReqRequestAccountVerifyRequest param) {

    }

    @Override
    public void companyAccountVerify(UmsMerchantReqCompanyAccountVerifyRequest companyAccountVerifyRequest) {

    }

    @Override
    public void smsSend(MerchantRegSmsSendBO merchantRegSmsSendBO) {
        GcPayProperties gcPayProperties = initGcPayConfig(merchantRegSmsSendBO.getOrgPaymentChannelId());
        GcMerchantRegSmsSendReq smsSendReq = new GcMerchantRegSmsSendReq();
        smsSendReq.setApplyNo(merchantRegSmsSendBO.getChannelRegNo());
        GcBaseResp<String> smsSendRes = new GcPayChannel(gcPayProperties).smsSend(smsSendReq);
    }

    /**
     * 短信验证码验证
     *
     * @param merchantRegSmsVerifyBO
     */
    @Override
    public void smsVerify(MerchantRegSmsVerifyBO merchantRegSmsVerifyBO) {
        GcPayProperties gcPayProperties = initGcPayConfig(merchantRegSmsVerifyBO.getOrgPaymentChannelId());
        GcMerchantRegVerifyReq verifyReq = new GcMerchantRegVerifyReq();
        verifyReq.setApplyNo(merchantRegSmsVerifyBO.getChannelRegNo());
        // 1-短信验证
        verifyReq.setType("1");
        verifyReq.setSmsCode(merchantRegSmsVerifyBO.getSmsCode());
        GcBaseResp<String> smsVerify = new GcPayChannel(gcPayProperties).smsVerify(verifyReq);
    }

    @Override
    public String agreementSign(UmsMerchantReqAgreementSignRequest agreementSignRequest) {
        return null;
    }

    @Override
    public MerchantRegStatusQueryResDTO queryRegisterStatus(UmsMerchantReqStatusQueryRequest request) {
        return null;
    }

    @Override
    public MerchantRegStatusEnums nextFlow(MerchantRegStatusEnums currentFlow, MerchantTypeEnums merchantType) {
        Asserts.isTrue(null != currentFlow && null != merchantType, "参数异常！");
        Asserts.isTrue(!merchantType.equals(MerchantTypeEnums.xiao_wei),"当前支付通道不支持小微商户入驻！");
        // 企业商户
        // 个体工商
        switch (currentFlow){
            case INIT:
                return MerchantRegStatusEnums.FIRST_AUDIT;
            case FIRST_AUDIT_SUCCESS:
                if(merchantType.equals(MerchantTypeEnums.qi_ye)){
                    return MerchantRegStatusEnums.CORPORATE_ACCOUNT_VERIFICATION;
                }
                return MerchantRegStatusEnums.SMS_VERIFICATION;
            case CORPORATE_ACCOUNT_VERIFICATION:
                return MerchantRegStatusEnums.CORPORATE_ACCOUNT_VERIFICATION_ING;
            case CORPORATE_ACCOUNT_VERIFICATION_ING:
                return MerchantRegStatusEnums.SIGNING_IN_PROGRESS;
            case CORPORATE_ACCOUNT_VERIFICATION_SUCCESS:
                return MerchantRegStatusEnums.SIGNING_IN_PROGRESS;
            case SIGNING_IN_PROGRESS:
                return MerchantRegStatusEnums.PROCESS_COMPLETED;
            case SMS_VERIFICATION:
                return MerchantRegStatusEnums.PROCESS_COMPLETED;
        }
        return null;
    }

    @Override
    public boolean needSign() {
        return false;
    }

    @Override
    public ChannelNotifyMessage callbackMsg(Map<String, Object> paramsMap) {
        ChannelNotifyMessage channelNotifyMessage = new ChannelNotifyMessage();
        // 进件id
        channelNotifyMessage.setAccesserId(MapUtils.getString(paramsMap, "applyNo"));
        channelNotifyMessage.setChannelCode(PaymentChannelEnum.gao_cheng_nong_hang.getCode());
        channelNotifyMessage.setMessageBody(paramsMap);
        return channelNotifyMessage;
    }

    private GcPayProperties initGcPayConfig(Long orgPaymentChannelId) {
        GcChannelProperties.GcChannelPropertiesItem properties = gcChannelProperties.getByOrgPayChannelId(orgPaymentChannelId);
        GcPayProperties gcPayProperties = new GcPayProperties();
        gcPayProperties.setAccessId(properties.getAccessId());
        gcPayProperties.setAccessSecret(properties.getAccessSecret());
        gcPayProperties.setHost(properties.getHost());
        gcPayProperties.setMchNo(properties.getMchNo());
        gcPayProperties.setNotifyUrl(properties.getNotifyUrl());
        return gcPayProperties;
    }
}
